package gxm

import (
	"fmt"

	"gitee.com/liumou_site/logger"
)

// ReadCol 读取指定列数据
//
// 参数：
//
//	col - 列号，从0开始（0表示第A列）
//
// 返回值：
//
//	*ApiRead - 支持链式调用的ApiRead指针
//
// 说明：
//   - 如果col为负数，会设置api.Err错误并返回
//   - 需要先调用ReadAll()读取数据后才能使用
//   - 返回的数据存储在DataRow字段中
//   - 支持链式操作，可以连续调用多个方法
//
// 示例：
//
//	reader.ReadAll().ReadCol(0)  // 读取第A列
//	reader.ReadCol(1)           // 读取第B列
func (api *ApiRead) ReadCol(col int) *ApiRead {
	// 参数验证：检查列号是否为负数
	if col < 0 {
		api.Err = fmt.Errorf("列号不能为负数")
		logger.Error(api.Err)
		return api
	}

	// 验证是否已经读取数据
	if len(api.Data) == 0 {
		api.Err = fmt.Errorf("请先读取数据再提取列")
		logger.Error(api.Err)
		return api
	}

	// 检查列号是否超出数据范围
	if col >= len(api.Data[0]) {
		api.Err = fmt.Errorf("列号%d超出数据范围，最大列号为%d", col, len(api.Data[0])-1)
		logger.Error(api.Err)
		return api
	}

	// 提取指定列数据
	var colData []string
	for _, row := range api.Data {
		if col < len(row) {
			colData = append(colData, row[col])
		} else {
			colData = append(colData, "") // 如果该行该列不存在，添加空字符串
		}
	}

	api.DataRow = colData
	logger.Info("成功提取第%d列数据，共%d行", col+1, len(colData))
	return api
}

// ReadColRange 读取指定列范围数据
//
// 参数：
//
//	startCol - 起始列号，从0开始
//	endCol   - 结束列号（包含），必须大于等于startCol
//
// 返回值：
//
//	*ApiRead - 支持链式调用的ApiRead指针
//
// 说明：
//   - 如果参数无效（负数、endCol < startCol），会设置api.Err错误并返回
//   - 需要先调用ReadAll()读取数据后才能使用
//   - 返回的数据存储在DataR字段中，每行是一个字符串切片
//   - 支持链式操作，可以连续调用多个方法
//
// 示例：
//
//	reader.ReadAll().ReadColRange(0, 2)  // 读取A-C列
//	reader.ReadColRange(1, 3)            // 读取B-D列
func (api *ApiRead) ReadColRange(startCol, endCol int) *ApiRead {
	// 参数验证
	if startCol < 0 || endCol < 0 {
		api.Err = fmt.Errorf("列号不能为负数")
		logger.Error(api.Err)
		return api
	}

	if endCol < startCol {
		api.Err = fmt.Errorf("结束列号必须大于等于起始列号")
		logger.Error(api.Err)
		return api
	}

	// 验证是否已经读取数据
	if len(api.Data) == 0 {
		api.Err = fmt.Errorf("请先读取数据再提取列范围")
		logger.Error(api.Err)
		return api
	}

	// 检查列范围是否有效
	if startCol >= len(api.Data[0]) {
		api.Err = fmt.Errorf("起始列号%d超出数据范围，最大列号为%d", startCol, len(api.Data[0])-1)
		logger.Error(api.Err)
		return api
	}

	if endCol >= len(api.Data[0]) {
		api.Err = fmt.Errorf("结束列号%d超出数据范围，最大列号为%d", endCol, len(api.Data[0])-1)
		logger.Error(api.Err)
		return api
	}

	// 提取指定列范围数据
	var rangeData [][]string
	for _, row := range api.Data {
		var newRow []string
		for col := startCol; col <= endCol && col < len(row); col++ {
			newRow = append(newRow, row[col])
		}
		// 如果需要的列数多于实际列数，补充空字符串
		for len(newRow) < (endCol - startCol + 1) {
			newRow = append(newRow, "")
		}
		rangeData = append(rangeData, newRow)
	}

	api.DataR = rangeData
	logger.Info("成功提取第%d到第%d列数据，共%d行%d列", startCol+1, endCol+1, len(rangeData), endCol-startCol+1)
	return api
}

// ReadCols 读取多列数据（非连续列）
//
// 参数：
//
//	cols - 列号切片，指定要读取的列
//
// 返回值：
//
//	*ApiRead - 支持链式调用的ApiRead指针
//
// 说明：
//   - 如果任意列号为负数，会设置api.Err错误并返回
//   - 需要先调用ReadAll()读取数据后才能使用
//   - 返回的数据存储在DataR字段中，每行是一个字符串切片
//   - 支持链式操作，可以连续调用多个方法
//
// 示例：
//
//	reader.ReadAll().ReadCols([]int{0, 2, 4})  // 读取A、C、E列
//	reader.ReadCols([]int{1, 3})               // 读取B、D列
func (api *ApiRead) ReadCols(cols []int) *ApiRead {
	// 参数验证
	for _, col := range cols {
		if col < 0 {
			api.Err = fmt.Errorf("列号不能为负数")
			logger.Error(api.Err)
			return api
		}
	}

	// 验证是否已经读取数据
	if len(api.Data) == 0 {
		api.Err = fmt.Errorf("请先读取数据再提取列")
		logger.Error(api.Err)
		return api
	}

	// 检查列号是否都有效
	maxCol := len(api.Data[0]) - 1
	for _, col := range cols {
		if col > maxCol {
			api.Err = fmt.Errorf("列号%d超出数据范围，最大列号为%d", col, maxCol)
			logger.Error(api.Err)
			return api
		}
	}

	// 提取指定多列数据
	var colsData [][]string
	for _, row := range api.Data {
		var newRow []string
		for _, col := range cols {
			if col < len(row) {
				newRow = append(newRow, row[col])
			} else {
				newRow = append(newRow, "") // 如果该行该列不存在，添加空字符串
			}
		}
		colsData = append(colsData, newRow)
	}

	api.DataR = colsData
	logger.Info("成功提取指定列数据，共%d行%d列", len(colsData), len(cols))
	return api
}
